<template>
	<div class="node">
		<div class="header">
			<el-form inline>
				<el-form-item label="节点">
					<el-select class="width-150" v-model="nodeName" placeholder="请选择节点" v-loading="!nodeName" @change="getNodeMon">
						<el-option v-for="node of nodeList" :key="node.nodeName" :value="node.nodeName" :label="node.nodeName" />
					</el-select>
				</el-form-item>
			</el-form>
		</div>
		<div class="content">
			<el-card>
				<Line title="CPU" name="cpu" :data="state.cpuData" :x-interval-show="2" y-unit="%" />
			</el-card>
			<el-card>
				<Line title="内存" name="memory" :data="state.memoryData" :x-interval-show="2" y-unit="B" />
			</el-card>
			<el-card>
				<Line title="网络接收负载" name="receiveLoad" :data="state.receiveLoadData" :x-interval-show="2" y-unit="B" />
			</el-card>
			<el-card>
				<Line title="网络发送负载" name="sendLoad" :data="state.sendLoadData" :x-interval-show="2" y-unit="B" />
			</el-card>
			<el-card>
				<Line title="网络接收每秒丢包数 " name="receiveLoss" :data="state.receiveLossData" :x-interval-show="2" y-unit="pps" />
			</el-card>
			<el-card>
				<Line title="网络发送每秒丢包数 " name="sendLoss" :data="state.sendLossData" :x-interval-show="2" y-unit="pps" />
			</el-card>
			<el-card>
				<Line title="网络接收每秒错包数" name="receiveError" :data="state.receiveErrorData" :x-interval-show="2" y-unit="pps" />
			</el-card>
			<el-card>
				<Line title="网络发送每秒错包数" name="sendError" :data="state.sendErrorData" :x-interval-show="2" y-unit="pps" />
			</el-card>
			<el-card class="w100">
				<Line title="网络重传率" name="retry" :data="state.retryData" y-unit="%" />
			</el-card>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { defineAsyncComponent, inject, onUnmounted, reactive, ref, watch } from 'vue';
import { useMonitorApi } from '/@/api/monitor-center';
import { dayjs } from 'element-plus';
import { lineTimeHandle, fillDates } from '/@/utils/other';
import { LineChartData } from '/@/types';
import { memoryMap } from '/@/utils/const';

interface DataState{
	cpuData:LineChartData;
	memoryData:LineChartData;
	receiveLoadData:LineChartData;
	sendLoadData:LineChartData;
	receiveLossData:LineChartData;
	sendLossData:LineChartData;
	receiveErrorData:LineChartData;
	sendErrorData:LineChartData;
	retryData:LineChartData;
}

const Line = defineAsyncComponent(() => import('/@/components/echarts/line.vue'));

const monitorApi = useMonitorApi();
const nodeList = inject<any[]>('node-list', []);
const nodeName = ref();
const state = reactive<DataState>({
	cpuData: {
		seriesNames: [],
		seriesData: []
	},
	memoryData: {
		seriesNames: [],
		seriesData: []
	},
	receiveLoadData: {
		seriesNames: [],
		seriesData: []
	},
	sendLoadData: {
		seriesNames: [],
		seriesData: []
	},
	receiveLossData: {
		seriesNames: [],
		seriesData: []
	},
	sendLossData: {
		seriesNames: [],
		seriesData: []
	},
	receiveErrorData: {
		seriesNames: [],
		seriesData: []
	},
	sendErrorData: {
		seriesNames: [],
		seriesData: []
	},
	retryData: {
		seriesNames: [],
		seriesData: []
	}
});
const datetimerange = inject('datetimerange', ref());
const defaultdaterange = inject('defaultdaterange', ref());
// get data
const getNodeMon = () => {
	if (!nodeName.value) return;
	const params = {
		nodeName: nodeName.value,
		durationVO: {
			start: datetimerange.value ? datetimerange.value[0] : dayjs().subtract(defaultdaterange.value[0], defaultdaterange.value[1]).format('YYYY-MM-DD HH:mm:ss'),
			end: datetimerange.value ? datetimerange.value[1] : dayjs().format('YYYY-MM-DD HH:mm:ss'),
		}
	};
	monitorApi.getNodeMon(params).then((res:any) => {
		const cpu = fillDates(params.durationVO?.start, res.data.cpu);
		const memory = fillDates(params.durationVO?.start, res.data.memory);
		const receiveLoad = fillDates(params.durationVO?.start, res.data.netWork.load.receive);
		const sendLoad = fillDates(params.durationVO?.start, res.data.netWork.load.transmit);
		const receiveLoss = fillDates(params.durationVO?.start, res.data.netWork.dropRate.receive);
		const sendLoss = fillDates(params.durationVO?.start, res.data.netWork.dropRate.transmit);
		const receiveError = fillDates(params.durationVO?.start, res.data.netWork.errorRate.receive);
		const sendError = fillDates(params.durationVO?.start, res.data.netWork.errorRate.transmit);
		const retry = fillDates(params.durationVO?.start, { '重传率': res.data.netWork.retransRate });
		state.cpuData = lineTimeHandle(cpu, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(1));
		});
		state.memoryData = lineTimeHandle(memory, memoryMap, (data) => {
			if (typeof (data) !== 'number') return data;
			return Math.round(data);
		});
		state.receiveLoadData = lineTimeHandle(receiveLoad, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
		state.sendLoadData = lineTimeHandle(sendLoad, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
		state.receiveLossData = lineTimeHandle(receiveLoss, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
		state.sendLossData = lineTimeHandle(sendLoss, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
		state.receiveErrorData = lineTimeHandle(receiveError, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
		state.sendErrorData = lineTimeHandle(sendError, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});

		state.retryData = lineTimeHandle(retry, undefined, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat((data * 100).toFixed(3));
		});
	}).catch(() => {
		state.cpuData = lineTimeHandle();
		state.memoryData = lineTimeHandle();
		state.receiveLoadData = lineTimeHandle();
		state.sendLoadData = lineTimeHandle();
		state.receiveLossData = lineTimeHandle();
		state.sendLossData = lineTimeHandle();
		state.receiveErrorData = lineTimeHandle();
		state.sendErrorData = lineTimeHandle();
		state.retryData = lineTimeHandle();
	});
};

const activeTab = inject('activeTab', ref('node'));
const interval = inject('interval', ref(5000));
const timer = ref();
// Start the timer and call the interface immediately
const openTimer = () => {
	if (!timer.value) {
		getNodeMon();
		timer.value = setInterval(getNodeMon, interval.value);
	}
};
// close Timer
const closeTimer = () => {
	if (timer.value) {
		clearInterval(timer.value);
		timer.value = null;
	}
};
const handle = () => {
	if (activeTab.value === 'node') {
		if (nodeName.value) {
			if (datetimerange.value) {
				getNodeMon();
				closeTimer();
			} else {
				openTimer();
			}
		}
	} else {
		closeTimer();
	}
};
// Listen to node list data
watch(
	nodeList,
	val => {
		nodeName.value = val[0]?.nodeName;
		handle();
	},
	{
		immediate: true
	}
);
// Switch to the current tab and turn on polling
watch(
	activeTab,
	() => {
		handle();
	},
	{
		immediate: true
	}
);
// Monitoring time range change
watch(
	datetimerange,
	() => {
		handle();
	},
);
// Monitoring time interval change
watch(
	interval,
	() => {
		// Reset timer
		if (timer.value) {
			clearInterval(timer.value);
			timer.value = setInterval(getNodeMon, interval.value);
		}
	}
);
onUnmounted(() => {
	closeTimer();
});
</script>
<style lang="scss" scoped>

</style>